<?php

namespace App\Resource\Orders;

use App\Model\Goods\Good;
use App\Model\Orders\OrderGood;
use Hyperf\Resource\Json\JsonResource;
use Hyperf\Stringable\Str;
use function Hyperf\Config\config;

/**
 * @property int $id
 * @property int $user_id 用户ID
 * @property int $shop_id 店铺ID
 * @property int $app_id 应用ID
 * @property string $no 订单号码
 * @property string $merchant_no 商家单号
 * @property string $paid_no 支付单号
 * @property string $transaction_id 支付流水号
 * @property string $consignee 收货人姓名
 * @property string $address 收货人详细地址
 * @property string $mobile 收货人手机号码
 * @property string $prov 收货省
 * @property string $city 收货市
 * @property string $area 收货区
 * @property string $shipping_at 发货时间
 * @property float $paid_amount 实际支付金额
 * @property string $total_amount 总金额
 * @property string $postage_amount 邮费
 * @property array $discount_amount 折扣金额
 * @property string $time_expire 订单结束时间
 * @property string $confirm_at 确认收货时间
 * @property string $complete_at 完成时间
 * @property string $paid_at 支付时间
 * @property string $refund_at 退款时间
 * @property string $user_note 用户留言
 * @property int $status 订单状态|{"1":"待支付","2":"待发货","3":"待收货","4":"已收货","5":"已完成","6":"已取消","7":"已关闭"}
 * @property int $pay_status 支付状态|{"1":"待支付","2":"部分支付","3":"已支付","4":"部分退款","5":"已退款","6":"申请退款中","7":"拒绝退款"}
 * @property string $payer_name 支付人姓名
 * @property string $payer_no 支付人身份证号码
 * @property string $payer_mobile 支付人手机号码
 * @property array $payer 实名信息
 * @property string $attach 附加数据
 * @property string $source 订单来源
 * @property int $auto_erp 自动推送ERP
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 */
class OrderResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array
     */
    public function toArray(): array
    {
        return parent::toArray();
    }

    /**
     * Transform the resource into an array for pay.
     * @param string $payCode
     * @return array
     */
    public function toPayArray(): array
    {
        $action = 'to'.Str::ucfirst($this->pay_code).'Array';

        return $this->{$action}();
    }

    /**
     * Transform the resource into an array for safepayMini.
     * @return array
     */
    protected function toSafepayMiniArray(): array
    {
        return [
            'out_trade_no' => $this->no,
            'payMethon' => 'NeoPay',
            'amount' => $this->paid_amount,
            'description' => "跨境订单支付:{$this->no}",
            'storeName' => $this->shop->name,
            'openid' => $this->payer['openid']
        ];
    }

    /**
     * Transform the resource into an array for sandpayMini.
     * @param $params
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function toSandpayMiniArray(): array
    {
        $payerInfo = [
            'subUserId' => $this->payer['openid'],
            'frontUrl' => getUrl('publics/v2/payment/notify/sandpay/mini')
        ];
        return [
            'marketProduct' => 'CSDB',
            'outReqTime' => date('YmdHis'),
            'outOrderNo' => $this->merchant_no,
            'description' => "跨境订单支付:{$this->no}",
            'goodsClass' => '01',
            'amount' => $this->paid_amount,
            'payType' => 'WXPAY',
            'payMode' => 'MINI',
            'payerInfo' => $payerInfo,
            'notifyUrl' => getUrl('publics/v2/payment/notify/sandpay/mini')
        ];
    }

    /**
     * Transform the resource into an array for neopayMini.
     * @return array[]
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function toNeopayMiniArray(): array
    {
        return [
            'data' => [
                'openid' => $this->payer['openid'],
                'tradeamt' => $this->paid_amount,
                'body' => "{$this->merchant_no}",
                'backUrl' => getUrl('publics/v1/payment/notify/neopay/mini'),
            ]
        ];
    }

    /**
     * Transform the resource into an array for neopayMini.
     * @return array[]
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function toNeopayWechatArray(): array
    {
        return [
            'data' => [
                'openid' => $this->payer['openid'],
                'tradeamt' => $this->paid_amount,
                'body' => "{$this->merchant_no}",
                'backUrl' => getUrl('publics/v1/payment/notify/neopay/mini'),
            ]
        ];
    }

    /**
     * Transform the resource into an array for wechatMini.
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function toWechatMiniArray(): array
    {
        return [
            'description' => "跨境订单支付:{$this->merchant_no}",
            'out_trade_no' => $this->merchant_no,
            'payer' => [
                'openid' => $this->payer['openid'],
            ],
            'amount' => [
                'total' => intval($this->paid_amount * 100),
                'currency' => 'CNY'
            ],
            'notify_url' => getDomain()."/publics/v1/payment/notify/wechat/mini/{$this->shop_id}",
        ];
    }

    /**
     * Transform the resource into an array for sumpayMini.
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function toSumpayMiniArray(): array
    {
        $goodsModels = $this->goods;
        $goodsName = '';
        $goodsNum = 0;
        /** @var OrderGood $model */
        foreach ($goodsModels as $model) {
            if (!$goodsName) {
                $goodsName = $model->good['name'];
            }
            $goodsNum += $model->num;
        }

        return [
            'trade_code' => 'T0002',
            'user_id' => $this->user_id,
            'order_no' => $this->merchant_no,
            'order_time' => date('YmdHis'),
            'order_amount' => $this->paid_amount,
            'notify_url' => getDomain(). "/publics/v1/payment/notify/sumpay/mini/{$this->shop_id}",
            'currency' => 'CNY',
            'goods_name' => $goodsName,
            'goods_num' => $goodsNum,
            'goods_type' => '1',
//            'identity' => json_encode([
//                'name' => $this->payer_name,
//                'number' => $this->payer_no
//            ], JSON_UNESCAPED_UNICODE),
            'sp_open_id' => $this->payer['openid']

        ];
    }

    /**
     * Transform the resource into an array for chinapnrpayMini.
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function toChinapnrpayMiniArray(): array
    {
        $goodsModels = $this->goods;
        $goodsName = '';
        $goodsNum = 0;
        /** @var OrderGood $model */
        foreach ($goodsModels as $model) {
            if (!$goodsName) {
                $goodsName = $model->good['name'];
            }
            $goodsNum += $model->num;
        }
        if (count($goodsModels) > 1) {
            $goodsName .= '等多个商品';
        }

        return [
            'pageUrl' => getDomain(). "/publics/v1/payment/notify/chinapnrpay/mini/{$this->shop_id}",
            'bgUrl' => getDomain(). "/publics/v1/payment/notify/chinapnrpay/mini/{$this->shop_id}",
            'terminalId' => '0010001',
            'customerId' => '',
            'deviceType' => '2',
            'payType' => '8',
            'orderId' => $this->merchant_no,
            'orderAmount' => intval($this->paid_amount * 100),
            'orderTime' => date('YmdHis'),
            'productName' => $goodsName,
            'productNum' => $goodsNum,
            'productId' => '100204',
            'openId' => $this->payer['openid'],
            'payerName' => $this->payer_name,
            'payerIdentityCard' => Str::upper($this->payer_no),
//            'payerName' => '王文斌',
//            'payerIdentityCard' => '411081199004235955',
        ];
    }

    /**
     * Transform the resource into an array for query.
     * @param string $payCode
     * @return array
     */
    public function toQueryArray(string $payCode='sandpayMini'): array
    {
        $action = 'to'.Str::ucfirst($this->pay_code).'QueryArray';

        return $this->{$action}();
    }

    /**
     * Transform the resource into an array for SandpayMini.
     * @return string[]
     */
    protected function toSandpayMiniQueryArray(): array
    {
        return [
            'outOrderNo' => $this->merchant_no
        ];
    }

    /**
     * Transform the resource into an array for NeopayMini.
     * @return array
     */
    protected function toNeopayMiniQueryArray(): array
    {
        return [
            'trace' => $this->paid_no,
            'type' => 'WAP'
        ];
    }

    /**
     * Transform the resource into an array for SumpayMini.
     * @return string[]
     */
    protected function toSumpayMiniQueryArray(): array
    {
        return [
            'order_no' => $this->merchant_no
        ];
    }

    /**
     * Transform the resource into an array for query.
     * @param string $payCode
     * @return array
     */
    public function toQueryDeclareArray(): array
    {
        $action = 'to'.Str::ucfirst($this->pay_code).'QueryDeclareArray';

        return $this->{$action}();
    }

    /**
     * Transform the resource into an array for SumpayMini.
     * @return string[]
     */
    protected function toSumpayMiniQueryDeclareArray(): array
    {
        return [
            'order_no' => $this->paid_no
        ];
    }
}
